#ifndef HOST_H
#define HOST_H

#include "../types.h"
#include "../gfx/ge.h"
#include "../hle/__sceDisplay.h"

typedef enum
{
    RE_MATRIX_MODEL,
    RE_MATRIX_PROJ
} REMatrix;

typedef enum
{
    RE_CAPABILITY_ALPHA_TEST,
    RE_CAPABILITY_BLEND,
    RE_CAPABILITY_CULL_FACE,
    RE_CAPABILITY_DEPTH_TEST,
    RE_CAPABILITY_TEXTURE_2D,
    RE_CAPABILITY_DITHER,
    NUM_CAPABILITIES
} RECapability;

typedef enum
{
    RE_TEXENV_COMBINE_RGB,
    RE_TEXENV_COMBINE_ALPHA,
    RE_TEXENV_RGB_SCALE,
    RE_TEXENV_ALPHA_SCALE,
    RE_TEXENV_SRC0_RGB,
    RE_TEXENV_SRC1_RGB,
    RE_TEXENV_SRC2_RGB,
    RE_TEXENV_SRC0_ALPHA,
    RE_TEXENV_SRC1_ALPHA,
    RE_TEXENV_SRC2_ALPHA,
    RE_TEXENV_OPERAND0_RGB,
    RE_TEXENV_OPERAND1_RGB,
    RE_TEXENV_OPERAND2_RGB,
    RE_TEXENV_OPERAND0_ALPHA,
    RE_TEXENV_OPERAND1_ALPHA,
    RE_TEXENV_OPERAND2_ALPHA,
    RE_TEXENV_ENV_MODE
} RETexEnvParam;

typedef enum
{
    RE_TEXENV_MODULATE,
    RE_TEXENV_DECAL,
    RE_TEXENV_BLEND,
    RE_TEXENV_REPLACE,
    RE_TEXENV_ADD,
    RE_TEXENV_INTERPOLATE,
    RE_TEXENV_SUBTRACT,
    RE_TEXENV_TEXTURE,
    RE_TEXENV_CONSTANT,
    RE_TEXENV_PREVIOUS,
    RE_TEXENV_SRC_COLOR,
    RE_TEXENV_SRC_ALPHA,
    RE_TEXENV_COMBINE
} RETexEnvValue;

typedef enum
{
    RE_TEXFMT_16BIT_BGR5650,
    RE_TEXFMT_16BIT_ABGR5551,
    RE_TEXFMT_16BIT_ABGR4444,
    RE_TEXFMT_32BIT_ABGR8888
} RETexFormat;

typedef struct
{
    u8 inited;
    u32 length;
    u32 lastTime;
    u8 repeat;
#ifndef UNIX
    u64 ticksPerSecond;
#endif
} Timer;

typedef enum
{
    SOUND_BUFFERED,
    SOUND_PLAYING,
    SOUND_MAXREACHED
} SoundType;

typedef enum
{
    CTRL_SELECT = 0,
    CTRL_START,
    CTRL_UP,
    CTRL_RIGHT,
    CTRL_DOWN,
    CTRL_LEFT,
    CTRL_LTRIGGER,
    CTRL_RTRIGGER,
    CTRL_TRIANGLE,
    CTRL_CIRCLE,
    CTRL_CROSS,
    CTRL_SQUARE
} Buttons;

/**********
 * WINDOW *
 **********/

/* Inits the window; returns 0 if all went OK, otherwise -1 */
s32 host_winInit();

/* Quits the window */
void host_winQuit();

/* Sets the window title (its second part; set to NULL to show only the name of the emulator) */
void host_setWinTitle(char *title);

/* Notice the frame changed (useful for FPS calculation */
void host_nextFrame();

/* Inits timing, etc. before creating the window; returns 0 if all went OK, otherwise -1 */
s32 host_init();

/* Frees timing, etc. handling */
void host_free();

/* Finishes the frame; waits for the actual draws to finish and sync the screen */
void host_frameFinish();

/* Synchronizes events for all its uses */
void host_syncEvents();

/* Returns 1 if client is exiting (escape pressed, window closed, ..), otherwise 0 */
u8 host_isQuit();

/* Returns OR'ed number of all the pressed buttons on the virtual PSP (see CTRL_*) */
u32 host_getBut();

/**********
 * TIMING *
 **********/

/* Inits a timer, occuring all the 'length' ms if 'repeat' is set to 1 or just one time in 'length' ms if 'repeat' is set to 0, and returns it */
Timer host_initTimer(u32 length, u8 repeat);

/* Tests a timer: return 1 if enough time passed, and then frees the timer if 'repeat' was set to 0, otherwise return 0 */
u8 host_testTimer(Timer *timer);

/* Tell the timer to update the last time it occured, which means it will occur next in the 'length' ms of the timer */
void host_updateTimerTime(Timer *timer);

/***********
 * DISPLAY *
 ***********/

/* Inits & frees display */
void host_dispInit();
void host_dispFree();

/* Returns 1 if the framebuffer as been set and can be used, otherwise 0 */
u8 host_fbIsSet();

/* Sets the actual frame buffer infos (framebuffer width, pixel format, size of the framebuffer) */
void host_setFb(u32 lineSize, ScePixelFormat pixelSize, u32 allocSize);

/* Synchronizes framebuffer on the screen */
void host_syncFb(u8 *realFB);

/* Waits the current 3d drawing to complete */
void host_dispFinish();

/* Inits a pointer to the 3d scene */
void *host_initScenePtr();

/* Frees this pointer */
void host_freeScenePtr();

/******
 * GE *
 ******/

/* Inits & frees GE */
void host_geInit();
void host_geFree();

/* Resets the view & modelview matrices */
void host_resetMatrices();

/* Enables/disables a capatibility (see RECapability) depending on the "enable" argument */
void host_setCapability(RECapability cap, u8 enable);

/* Use the default orthogonal projection */
void host_setOrthoProj();

/* Sets viewport */
void host_setViewport(u32 x, u32 y, u32 w, u32 h);

/* Loads a projection matrix */
void host_loadProjMatrix(float *m);

/* Sets the depth range (near and far) */
void host_setDepthRange(double near, double far);

/* Sets the shade model */
void host_setShadeModel(GEShadeModel model);

/* Draws a primitive of type 'prim', with 'numVerts' vertices, and with vertex coordinates in vertexArr, texture coordinates in texCoordArr and colors in colorArr */
void host_drawPrimitive(float *vertexArr, float *texCoordArr, float *colorArr,
                       GEPrimitiveType prim, u32 numVerts);

/* Clears the different buffers if their argument is set to 1 */
void host_clear(u8 color, u8 stencil, u8 depth);

/* Sets buffer masks */
void host_setMask(u8 color, u8 alpha, u8 depth);

/* Sets the orientation of the front-facing polygons */
void host_setFrontFace(GEFrontFaceType frontFace);

/* Sets the depth comparison function */
void host_setDepthFunc(GEZTest ztst);

/* Sets the blend equation */
void host_setBlendEquation(GEBlendFunction func);

/* Sets the blend source & destination factors */
void host_setBlendFactors(u8 sfactor, u8 dfactor);

/* Sets the blend color */
void host_setBlendColor(float color[4]);

/* Sets the alpha test: function & reference value */
void host_setAlphaTest(GEAlphaFunction func, float ref);

/************
 * TEXTURES *
 ************/

/* Generates a texture and returns its id */
u32 host_genTex();

/* Removes a texture */
void host_delTex(u32 id);

/* Sets the actual texture */
void host_setTex(u32 texId);

/* Sets actual texture with an array, and its size and format */
void host_setTexImage(u32 level, u32 width, u32 height, RETexFormat format, void *texArray);

/* Sets texture parameters: S clamp, T clamp, magnifying filter, minifying filter */
void host_setTexParam(u8 sClamp, u8 tClamp, u8 magFilt, u8 minFilt);

/* Sets texture RGB scale */
void host_setTexRgbScale(float scale);

/* Sets texture environment color */
void host_setTexEnvColor(float color[4]);

/* Sets a texture environment parameter */
void host_setTexEnvParam(RETexEnvParam param, RETexEnvValue value);

/* Sets the texture pixel storing row length & alignment */
void host_setPixelStore(u32 rowLength, u32 alignment);

/*********
 * AUDIO *
 *********/

/* Inits audio */
void host_initAudio(u8 numChannels);

/* Frees audio */
void host_freeAudio();

/* Buffers a sound to play it (ran from the interpreter thread), and returns 1 if the ringbuffer is full */
u8 host_queueBuffer(void *sndBuf, u32 count, u8 stereo, u8 channel);

/* Update audio: really play sounds (ran from the audio thread) */
void host_audioUpdate();

#endif

